Los JOINs
Los JOINs permiten combinar información procedente de varias tablas utilizando campos relacionados entre sí.
En bases de datos reales, los datos están distribuidos para evitar redundancia y mejorar la integridad.
¿Por qué existen?
- Separar entidades diferentes.
- Evitar duplicación de datos.
- Mantener consistencia.
- Escalar sistemas grandes.
- Optimizar almacenamiento.
Relación típica
| Tabla | Contenido |
|---|---|
| Clientes | Datos personales |
| Pedidos | Compras realizadas |
Ejemplo básico
SELECT Clientes.nombre, Pedidos.total
FROM Clientes
INNER JOIN Pedidos
ON Clientes.id_cliente = Pedidos.id_cliente;
Qué hace esta consulta
- Une Clientes y Pedidos.
- Relaciona ambas tablas mediante id_cliente.
- Muestra únicamente coincidencias.
INNER, LEFT y RIGHT
INNER JOIN
Devuelve solo registros coincidentes entre ambas tablas.
SELECT C.nombre, P.total
FROM Clientes C
INNER JOIN Pedidos P
ON C.id_cliente = P.id_cliente;
LEFT JOIN
Devuelve todas las filas de la tabla izquierda.
SELECT C.nombre, P.total
FROM Clientes C
LEFT JOIN Pedidos P
ON C.id_cliente = P.id_cliente;
RIGHT JOIN
Devuelve todas las filas de la tabla derecha.
SELECT C.nombre, P.total
FROM Clientes C
RIGHT JOIN Pedidos P
ON C.id_cliente = P.id_cliente;
Diferencias
| JOIN | Resultado |
|---|---|
| INNER | Solo coincidencias |
| LEFT | Todo izquierda + coincidencias |
| RIGHT | Todo derecha + coincidencias |
Gestión de Ventas en una Cadena de Retail
En una empresa de retail como El Corte Inglés, los JOINs permiten analizar clientes, pedidos y ventas.
Tablas principales
Clientes(
id_cliente,
nombre,
email,
provincia
)
Pedidos(
id_pedido,
id_cliente,
total,
fecha_compra
)
Clientes con compras
SELECT C.nombre, P.total
FROM Clientes C
INNER JOIN Pedidos P
ON C.id_cliente = P.id_cliente;
Clientes sin compras
SELECT C.nombre
FROM Clientes C
LEFT JOIN Pedidos P
ON C.id_cliente = P.id_cliente
WHERE P.id_pedido IS NULL;
Pedidos huérfanos
SELECT P.id_pedido
FROM Clientes C
RIGHT JOIN Pedidos P
ON C.id_cliente = P.id_cliente
WHERE C.id_cliente IS NULL;
Aplicaciones reales
- Marketing personalizado.
- Detección de errores.
- Auditoría de ventas.
- Segmentación comercial.
Introducción a FULL JOIN o FULL OUTER JOIN
FULL JOIN devuelve todas las filas de ambas tablas, coincidan o no.
Qué incluye
- Coincidencias entre tablas.
- Filas solo de la izquierda.
- Filas solo de la derecha.
Funcionamiento conceptual
| Situación | Resultado |
|---|---|
| Coincidencia | Se muestran ambas filas |
| Solo izquierda | Derecha = NULL |
| Solo derecha | Izquierda = NULL |
FULL OUTER JOIN
SELECT *
FROM Clientes
FULL OUTER JOIN Pedidos
ON Clientes.id_cliente = Pedidos.id_cliente;
FULL JOIN
Simulación en MySQL
MySQL requiere combinar LEFT JOIN y RIGHT JOIN usando UNION.
SELECT C.nombre, P.total
FROM Clientes C
LEFT JOIN Pedidos P
ON C.id_cliente = P.id_cliente
UNION
SELECT C.nombre, P.total
FROM Clientes C
RIGHT JOIN Pedidos P
ON C.id_cliente = P.id_cliente;
Qué hace UNION
- Combina resultados.
- Elimina duplicados.
- Genera conjunto final completo.
UNION ALL
SELECT nombre FROM Clientes
UNION ALL
SELECT nombre FROM Proveedores;
UNION ALL mantiene duplicados y es más rápido.
Subconsultas
Las subconsultas son consultas anidadas dentro de otras consultas SQL.
Ejemplo básico
SELECT nombre
FROM Clientes
WHERE id_cliente IN (
SELECT id_cliente
FROM Pedidos
WHERE total > 1000
);
Qué ocurre
- La subconsulta obtiene clientes.
- La consulta principal filtra nombres.
IN
Comprueba si un valor pertenece a un conjunto.
EXISTS
SELECT nombre
FROM Clientes C
WHERE EXISTS (
SELECT 1
FROM Pedidos P
WHERE P.id_cliente = C.id_cliente
);
Ventajas
- Consultas complejas.
- Filtrado avanzado.
- Lógica empresarial.
- Análisis profesional.
Gestión de una aerolínea
Las aerolíneas utilizan JOINs y subconsultas para relacionar pasajeros, reservas y vuelos.
Tablas
Pasajeros(
id_pasajero,
nombre,
email
)
Reservas(
id_reserva,
id_pasajero,
destino,
precio
)
FULL JOIN simulado
SELECT P.nombre, R.destino
FROM Pasajeros P
LEFT JOIN Reservas R
ON P.id_pasajero = R.id_pasajero
UNION
SELECT P.nombre, R.destino
FROM Pasajeros P
RIGHT JOIN Reservas R
ON P.id_pasajero = R.id_pasajero;
Pasajeros premium
SELECT nombre
FROM Pasajeros
WHERE id_pasajero IN (
SELECT id_pasajero
FROM Reservas
WHERE precio > 500
);
Objetivos empresariales
- Detectar inconsistencias.
- Encontrar clientes premium.
- Auditar reservas.
- Conciliar sistemas.
- Aplicar campañas comerciales.
Optimización
EXPLAIN
SELECT P.nombre, R.destino
FROM Pasajeros P
LEFT JOIN Reservas R
ON P.id_pasajero = R.id_pasajero;
EXPLAIN analiza cómo ejecuta MySQL la consulta.